﻿/*
----------------------------------
    Rodeo Game Engine
    Rodeo Renderer Module
    CGShaders.h - header file
    Copyright(c) Marcin Goryca
----------------------------------
*/
#ifndef RODEO_RENDERER_CGSHADERS_H_
#define RODEO_RENDERER_CGSHADERS_H_

#ifndef RODEO_GLLIBS_H_
#include "..\gllibs.h"
#endif    // RODEO_GLLIBS_H_

#ifndef RODEO_RENDERER_SHADERSINTERFACE_H_
#include "renderer\shadersinterface.h"
#endif    // RODEO_RENDERER_SHADERSINTERFACE_H_

/*
#ifndef RODEO_CORE_CONSTANTS_H_
#include "core\constants.h"
#endif
*/
namespace rodeorenderer
{
class CGShaders : public ShadersInterface
{
public:
    CGShaders()
    :context_(0),
     vs_program_(0),
     fs_program_(0),
     vs_program_name_(""),
     vs_filename_(""),
     vs_entry_("main"),
     fs_program_name_(""),
     fs_filename_(""),
     fs_entry_("main")
    {}
    virtual ~CGShaders(){}

    // Loads Shader from file
    // Parameter const char* string of filename
    // Parameter ShaderType - RODEO_VS, RODEO_FS
    // Returns unsigned int id of the shader program
    //TODO: This method doesn't work with CGShaders since
    // it returns unsigned int and CG Shaders use CGProgram struct
    virtual rodeocore::ui loadShaderFromFile(const char* filename, rodeocore::ShaderType st);

    // Loads Vertex Shader from file
    void loadVertexShader(std::string filename);

    // Inits Shaders
    virtual void init();

    // Uses Shader Program
    // Parameter unsigned int shader program id
    virtual void useShaderProgram(rodeocore::ui shader_program);

    // Gets string of Vertex Shader Program
    // Returns const char*
    virtual const char* getVertexProgramFile() const 
    {
        return vertex_program_file_;
    }

    // Sets string of Vertex Shader Program
    // Parameter const char* new vertex shader program filename
    virtual void setVertexProgramFile(const char* vpf)
    {
        vertex_program_file_ = vpf;
    }

    // Gets string of Fragment Shader Program
    // Returns const char* fragment shader program filename
    virtual const char* getFragmentProgramFile() const
    {
        return fragment_program_file_;
    }

    // Sets Fragment Shader Program string
    // Parameter const char* new string for fragment shader program filename
    virtual void setFragmentProgramFile(const char* fpf)
    {
        fragment_program_file_ = fpf;
    }

    // Gets Vertex Shader Id
    // Returns unsigned int id of the vertex shader
    virtual rodeocore::ui getVertexShader() const
    {
        return vertex_shader_;
    }

    // Sets Vertex Shader Id
    // Parameter unsigned int new id for vertex shader
    virtual void setVertexShader(rodeocore::ui id)
    {
        vertex_shader_ = id;
    }

    // Gets Fragment Shader Id
    // Returns unsigned int fragment shader id
    virtual rodeocore::ui getFragmentShader() const
    {
        return fragment_shader_;
    }

    // Sets Frrnsagment Shader Id
    // Parameter unsigned id new id for fragment shader
    virtual void setFragmentShader(rodeocore::ui id)
    {
        fragment_shader_ = id;
    }

    // Gets Shader Program Id
    // Returns unsigned int Shader Program Id
    virtual rodeocore::ui getProgram() const { return program_; }

    // Sets Shader Program Id
    // Parameter unsigned int new shader program id
    virtual void setProgram(rodeocore::ui program) { program_ = program; }

    // CG Specific functions

    // Gets CG Context
    // Returns CGContext
    CGcontext getContext() { return context_; }

    // Gets Vertex Shader Profile
    // Returns CGProfile
    CGprofile getVSProfile()const { return vs_profile_; }

    // Gets Vertex Shader Program
    // Returns CGProgram
    CGprogram getVSProgram()const { return vs_program_; }

    // Gets Fragment Shader Profile
    // Returns CGProfile
    CGprofile getFSProfile()const { return fs_profile_; }

    // Gets Fragment Shader Program
    // Returns CGProgram
    CGprogram getFSProgram()const { return fs_program_; }

    // Gets Vertex Shader Program Name
    // Returns string Shader Program Name
    std::string getVSProgramName()const { return vs_program_name_; }

    // Gets Vertex Shader Program File Name
    // Returns string Shader Program File Name
    std::string getVSFilename()const { return vs_filename_; }

    // Gets Vertex Shader Entry Point
    // Returns string Vertex Shader Entry Point
    std::string getVSEntryPoint()const { return vs_entry_; }

    // Gets Fragment Shader Program Name
    // Returns string Fragment Shader Program Name
    std::string getFSProgramName()const { return fs_program_name_; }

    // Gets Fragment Shader Filename
    // Returns string Fragment Shader Filename
    std::string getFSFilename() const { return fs_filename_; }

    // Gets Fragment Shader Entry Point
    // Returns Fragment Shader Entry Point
    std::string getFSEntryPoint()const { return fs_entry_; }

    // Sets Vertex Shader Program Name
    void setVSProgramName(std::string pn) { vs_program_name_ = pn; }

    // Sets Vertex Shader Filename
    // Parameter string new vertex shader filename
    void setVSFilename(std::string pfn) { vs_filename_ = pfn; }

    // Sets Vertex Shader Entry Point
    // Parameter string new vertex shader entry point
    void setVSEntryPoint(std::string vpn) { vs_entry_ = vpn; }

    // Sets Fragment Shader Program Name
    // Parameter string new fragment shader program name
    void setFSProgramName(std::string fpn){ fs_program_name_ = fpn; }

    // Sets Fragment Shader Filename
    // Parameter string new fragment shader filename
    void setFSFilename(std::string fpfn){ fs_filename_ = fpfn; }

    // Sets Fragment Shader Entry Point
    // Parameter string new fragment shader entry point
    void setFSEntryPoint(std::string fep){ fs_entry_ = fep; }

    // Inits CG Shaders
    void initCG();
    //void initCG(const char* pfn, const char* vpn);
    void initCG(std::string vertex_shader_filename, std::string vertex_entry_point, std::string fragment_shader_filename, std::string fragment_shader_entry_point);

    void bindProgram(CGprogram program);
    void enableProfile(CGprofile profile);
    void disableProfile(CGprofile profile);

    //CGparameter parameter_;

    // Texturing
    void enableTextureParameter(CGparameter param);
    void disableTextureParameter(CGparameter param);

    // Checks for CG Error
    void checkForError(std::string message);

//==== MEMBERS ====//
private:

    // CG Context for Shaders
    CGcontext context_;

    // Vertex Shader CG Profile 
    CGprofile vs_profile_;

    // Vertex Shader CG Program
    CGprogram vs_program_;

    // Fragment Shader CG Profile 
    CGprofile fs_profile_;

    // Fragment Shader CG Program
    CGprogram fs_program_;

    // Vertex Shader CG Program Name
    std::string vs_program_name_;

    // Vertex Shader CG Filename
    std::string vs_filename_;

    // Vertex Shader CG Entry Point
    // Entry Point, name of the function, e.g. 'main'
    std::string vs_entry_;

    // Fragment Shader CG Program Name
    std::string fs_program_name_;

    // Fragment Shader CG Filename
    std::string fs_filename_;

    // Fragment Shader Entry Point
    // Entry Point, name of the function, e.g. 'main'
    std::string fs_entry_;
};
}    //end of rodeorenderer namespace
#endif    //RODEO_RENDERER_CGSHADERS_H_